package com.jeeplus.test.jlnu.archivalInfo.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeeplus.file.config.FileProperties;
import com.jeeplus.file.repository.AccessoryRepository;
import com.jeeplus.sys.domain.Office;
import com.jeeplus.sys.service.OfficeService;
import com.jeeplus.sys.service.dto.OfficeDTO;
import com.jeeplus.sys.utils.UserUtils;
import com.jeeplus.test.jlnu.admissionInfo.domain.entity.AdmissionInfo;
import com.jeeplus.test.jlnu.admissionInfo.domain.entity.AllInfo;
import com.jeeplus.test.jlnu.admissionInfo.mapper.ExcelMapper;
import com.jeeplus.test.jlnu.archivalInfo.domain.entity.ArchParmerter;
import com.jeeplus.test.jlnu.archivalInfo.domain.entity.HangErrorEntity;
import com.jeeplus.test.jlnu.archivalInfo.domain.vo.ArchivalInfoReqVo;
import com.jeeplus.test.jlnu.archivalInfo.mapper.ArchivalInfoMapper;
import com.jeeplus.test.jlnu.archivalInfo.service.ArchivalInfoService;
import com.jeeplus.test.jlnu.fieldConfig.domain.FieldConfigEntity;
import com.jeeplus.test.jlnu.fieldConfig.mapper.ArchivalFieldConfigMapper;
import com.jeeplus.test.postgraduate.domain.vo.PostgraduateReqVo;
import com.jeeplus.test.website.websiteFile.domain.entity.WebsiteFile;
import com.jeeplus.test.website.websiteFile.service.WebsiteFileService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.*;

@Service
public class ArchivalInfoServiceImpl implements ArchivalInfoService {
    @Autowired
    private FileProperties fileProperties;

    @Autowired
    private AccessoryRepository accessoryRepository;

    @Value("${config.accessory.minIO.endpoint}")
    private String systemMac;

    private String FILE_SERVER = "/file";
    @Autowired
    private ArchivalInfoMapper archivalInfoMapper;
    @Autowired
    private WebsiteFileService websiteFileService;

    @Autowired
    private OfficeService officeService;

    @Override
    public Page<ArchivalInfoReqVo> getArchivalInfoPage(ArchivalInfoReqVo archivalInfoReqVo, Page<ArchivalInfoReqVo> page) {
        // 1. 获取分页结果和字段配置信息
        if (StringUtils.isNotEmpty(archivalInfoReqVo.getOfficeId())) {
            Office byId = officeService.getById(archivalInfoReqVo.getOfficeId());
            if("6".equals(byId.getType())){
                //如果是档案馆
                //获取机构下所有层级
                List<String> officesList = officeService.getOfficesTreeByParentId(archivalInfoReqVo.getOfficeId());
                officesList.add(archivalInfoReqVo.getOfficeId());
                archivalInfoReqVo.setOfficesList(officesList);
                archivalInfoReqVo.setOfficeId("");
            }
        }

        // 处理type
        if (StringUtils.isNotEmpty(archivalInfoReqVo.getApproveState())) {
            String[] arr = archivalInfoReqVo.getApproveState().split(",");
            List<String> list = Arrays.asList(arr);
            archivalInfoReqVo.setApproveStateList(list);
        }

        if (StringUtils.isNotEmpty(archivalInfoReqVo.getTransferState())) {
            String[] arr = archivalInfoReqVo.getTransferState().split(",");
            List<String> list = Arrays.asList(arr);
            archivalInfoReqVo.setTransferStateList(list);
        }

        Page<ArchivalInfoReqVo> archivalInfoPage = archivalInfoMapper.getArchivalInfoPage(archivalInfoReqVo, page);

        return archivalInfoPage;
    }

    @Override
    public int updateArchival(ArchivalInfoReqVo archivalInfoReqVo) {
        return archivalInfoMapper.updateArchival(archivalInfoReqVo);
    }

    @Override
    public int checkStuId(String studentId) {
        return archivalInfoMapper.checkStuId(studentId);
    }

    @Override
    public void addArchival(ArchivalInfoReqVo archivalInfoReqVo) {
         archivalInfoMapper.addArchival(archivalInfoReqVo);
    }

    @Override
    public void addAddmissionStuId(ArchivalInfoReqVo archivalInfoReqVo) {
        archivalInfoMapper.addAddmissionStuId(archivalInfoReqVo);
    }

    /**
     * 文件名都是学号+材料号命名，所以需要跟数据库中的学号和材料号做匹配，学号可能有多个，但是材料号只有一个，匹配上了就在这条数据上更新文件的url
     * @param files
     * @return
     */
    @Override
    public int hanging(MultipartFile[] files, HttpServletRequest request) {
        List<ArchivalInfoReqVo> archParmerterList = archivalInfoMapper.getStuIdAndMaterialId();
        List<Map<String, Object>> failedFiles = new ArrayList<>(); // 记录未挂接成功的文件

        for (MultipartFile file : files) {
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null) continue;

            // 提取文件名（去除扩展名）
            String fileName = originalFilename.substring(0, originalFilename.lastIndexOf("."));

            // 上传文件并获取返回的 fileId 和 fileUrl
            Map<String, String> upload = upload(request, file);
            String fileId = upload.get("id");

            boolean isMatched = false; // 记录是否匹配成功

            for (ArchivalInfoReqVo archParmerter : archParmerterList) {
                // 确保匹配的是【学号+材料号】的完整组合
                String expectedFileName = archParmerter.getStudentId() + archParmerter.getMaterialId();
                if (fileName.equals(expectedFileName)) {
                    // 只处理未挂接文件的情况
                    if (archParmerter.getFileId() == null) {
                        archParmerter.setFileId(fileId);
                        archivalInfoMapper.updateArchival(archParmerter);
                        isMatched = true;
                        break; // 一个文件只能匹配到一个档案，匹配成功后跳出循环
                    } else {
                        // 该档案已经挂接过，不允许重复挂接，记录失败
                        Map<String, Object> failedFile = new HashMap<>();
                        failedFile.put("fileName", originalFilename);
                        failedFile.put("reason", "文件已挂接");
                        failedFile.put("uploadTime", new Date());
                        failedFiles.add(failedFile);
                        isMatched = true; // 这里设置为 true，避免进入最后的未匹配逻辑
                        break;
                    }
                }
            }

            // 记录未成功挂接的文件信息
            if (!isMatched) {
                Map<String, Object> failedFile = new HashMap<>();
                failedFile.put("fileName", originalFilename);
                failedFile.put("reason", "未找到匹配的档案");
                failedFile.put("uploadTime", new Date());
                failedFiles.add(failedFile);
            }
        }

        // 处理未成功挂接的文件（可以写入数据库或日志）
        if (!failedFiles.isEmpty()) {
            logFailedFiles(failedFiles);
        }

        return 1;
    }

    /**
     * 记录未挂接成功的文件信息（存数据库或日志）
     */
    private void logFailedFiles(List<Map<String, Object>> failedFiles) {
        List<HangErrorEntity> errorRecords = new ArrayList<>();

        for (Map<String, Object> failedFile : failedFiles) {
            OfficeDTO officeDTO = UserUtils.getCurrentUserDTO().getOfficeDTO();
            String officeId = officeDTO.getId();
            HangErrorEntity hangErrorEntity = new HangErrorEntity();
            hangErrorEntity.setOfficeId(officeId);
            hangErrorEntity.setFileName((String) failedFile.get("fileName"));
            hangErrorEntity.setCreateTime(new Date()); // 记录当前时间
            hangErrorEntity.setReason((String) failedFile.get("reason")); // 失败原因从参数中获取
            errorRecords.add(hangErrorEntity);
        }

        if (!errorRecords.isEmpty()) {
            archivalInfoMapper.batchInsertFailedFiles(errorRecords);
        }
    }

    private Map<String, String> upload(HttpServletRequest request, MultipartFile file) {
        Calendar cal = Calendar.getInstance();
        Map<String, String> resultMap = new HashMap<>();

        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;

        String uploadPath = "/file/test" + "/" + year + "/" + month + "/";
        String minioPath = "/test" + "/" + year + "/" + month + "/";

        // 判断文件是否为空
        if (!file.isEmpty()) {
            String name = file.getOriginalFilename();
            if (fileProperties.isAvailable(name)) {
                // 文件保存
                //accessoryRepository.save(file, uploadPath, name);
                accessoryRepository.save(file, minioPath, name);

                // 生成唯一 ID
                String fileId = IdUtil.simpleUUID();

                // 生成 URL
                String fileUrl = systemMac  + FILE_SERVER + minioPath + name;

                // 保存到数据库
                WebsiteFile websiteFile = new WebsiteFile();
                websiteFile.setId(fileId);
                websiteFile.setFileUrl(fileUrl);
                websiteFile.setFileName(name);
                websiteFile.setBucketName(uploadPath);
                websiteFile.setBucketId(FILE_SERVER);
                websiteFile.setCreateTime(new Date());
                websiteFileService.save(websiteFile);

                // 将 ID 和 URL 放入 Map
                resultMap.put("id", fileId);
                resultMap.put("url", FILE_SERVER + "/download?uploadPath=" + uploadPath + "&name=" + name);

                return resultMap;
            } else {
                resultMap.put("error", "失败");
                return resultMap;
            }
        } else {
            resultMap.put("error", "失败");
            return resultMap;
        }
    }
    @Override
    public Map<String, Object> getFailedFiles(int page, int size) {
        int offset = (page - 1) * size;
        String id = UserUtils.getCurrentUserDTO().getOfficeDTO().getId();
        List<HangErrorEntity> failedFiles = archivalInfoMapper.getFailedFiles(offset, size,id);
        int total = archivalInfoMapper.countFailedFiles(id);

        Map<String, Object> result = new HashMap<>();
        result.put("total", total);
        result.put("list", failedFiles);
        return result;
    }

    @Override
    public WebsiteFile queryFileById(String fileId) {

        return websiteFileService.getById(fileId);
    }

    @Override
    public ArchivalInfoReqVo getArchivalInfoById(Integer infoId) {

        return archivalInfoMapper.getArchivalInfoById(infoId);
    }

    @Override
    public List<Map<String, String>> querylist(Map param) {
        return archivalInfoMapper.querylist(param);
    }

    @Override
    public List<AdmissionInfo> selectAllByOfficeId(ArchivalInfoReqVo archivalInfoReqVo) {
        // 1. 获取分页结果和字段配置信息
        if (StringUtils.isNotEmpty(archivalInfoReqVo.getOfficeId())) {
            Office byId = officeService.getById(archivalInfoReqVo.getOfficeId());
            if(byId != null && "6".equals(byId.getType())){
                //如果是档案馆
                //获取机构下所有层级
                List<String> officesList = officeService.getOfficesTreeByParentId(archivalInfoReqVo.getOfficeId());
                officesList.add(archivalInfoReqVo.getOfficeId());
                archivalInfoReqVo.setOfficesList(officesList);
                archivalInfoReqVo.setOfficeId("");
            }
        }

        // 处理type
        if (StringUtils.isNotEmpty(archivalInfoReqVo.getApproveState())) {
            String[] arr = archivalInfoReqVo.getApproveState().split(",");
            List<String> list = Arrays.asList(arr);
            archivalInfoReqVo.setApproveStateList(list);
        }


        List<AdmissionInfo> archivalInfoPage = archivalInfoMapper.selectAllByOfficeId(archivalInfoReqVo);

        return archivalInfoPage;
    }

    @Override
    public int batchUpdateArchiva(ArchivalInfoReqVo archivalInfoReqVo) {
        return  archivalInfoMapper.batchUpdateArchiva(archivalInfoReqVo.getAdmissionInfoList(),archivalInfoReqVo.getTransferState());
    }

}
